#include <pthread.h>
#include <functional>
#include <iostream>
#include "log.hpp"
#pragma once

using namespace LogMudule;

namespace ThreadModule
{
    
    using func_t = std::function<void()>;

    template<typename T>
    class Thread
    {
    public:
        Thread(T f = [](){std::cout << "当前回调为空" << std::endl;})
            : _func(f)
            , _isDetach(false)
            , _isRun(false)
        {
            _name = "thread - " + std::to_string(_count++);
        }

        static void* routine(void* args)
        {
            Thread* self = static_cast<Thread*>(args);
            if(self->_isDetach)
            {
                self->Detach();
            }
            pthread_setname_np(self->_tid, self->_name.c_str());
            self->_func();
            return nullptr;
        }

        void Detach()
        {
            if(_isDetach) return;
            _isDetach = true;
            pthread_detach(_tid);
            LOG((const int)LogLevel::DEBUG) << "线程已经分离!";
        }

        void Start()
        {
            _isRun = true;
            pthread_create(&_tid, nullptr, routine, this);
            sleep(1);
        }

        void Stop()
        {
            if(_isRun)
            {
                int n = pthread_cancel(_tid);
                if(n == 0)
                {
                    LOG((const int)LogLevel::DEBUG) << "线程取消成功!";
                    return;
                }
                else
                {
                    LOG((const int)LogLevel::DEBUG) << "线程取消失败!";
                    return;
                }
            }
        }

        void Join()
        {
            if(_isDetach)
            {
                LOG((const int)LogLevel::DEBUG) << "线程已经分离，不用等待!";
                return;
            }
            pthread_join(_tid, nullptr);
            LOG((const int)LogLevel::DEBUG) << "线程" << _name << "等待成功";
        }
    private:
        pthread_t _tid;

        std::string _name;

        bool _isRun;
        bool _isDetach;
        T _func;
        static int _count;
    };

    template<typename T>
    int Thread<T>::_count = 0;
};

